package com.lingx.web.core;

import com.lingx.web.LingxApp;

import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpRequestDecoder;
import io.netty.handler.codec.http.HttpResponseEncoder;
import io.netty.handler.stream.ChunkedWriteHandler;

/**
 * Netty Handler 初始化类
 * 
 */
final class HandlerInitializer extends ChannelInitializer<SocketChannel> {
    
    private int maxContentLength = 0;
     
    
    public HandlerInitializer(int maxContentLength) {
        this.maxContentLength = maxContentLength;
    }
    
    @Override
    protected void initChannel(SocketChannel ch) throws Exception {
        /*
         * ChannelInboundHandler按照注册的先后顺序执行，ChannelOutboundHandler按照注册的先后顺序逆序执行。
         * HttpRequestDecoder、HttpObjectAggregator、HttpHandler为InboundHandler
         * HttpContentCompressor、HttpResponseEncoder为OutboundHandler
         * 在使用Handler的过程中，需要注意：
         * 1、ChannelInboundHandler之间的传递，通过调用 ctx.fireChannelRead(msg) 实现；调用ctx.write(msg) 将传递到ChannelOutboundHandler。
         * 2、ctx.write()方法执行后，需要调用flush()方法才能令它立即执行。
         * 3、ChannelOutboundHandler 在注册的时候需要放在最后一个ChannelInboundHandler之前，否则将无法传递到ChannelOutboundHandler。
         * 4、Handler的消费处理放在最后一个处理。
         */
    	
    	HttpRequestHandler httpRequestHandler=LingxApp.SPRINGCONTEXT.getBean(HttpRequestHandler.class);
        ChannelPipeline pipeline = ch.pipeline();
        
        pipeline.addLast("decoder", new HttpRequestDecoder());
        pipeline.addLast("aggregator", new HttpObjectAggregator(maxContentLength));
        pipeline.addLast("encoder", new HttpResponseEncoder());
        // 启用gzip（由于使用本地存储文件，不能启用gzip）
        //pipeline.addLast(new HttpContentCompressor(1));
        pipeline.addLast(new ChunkedWriteHandler());
        // 将HttpRequestHandler放在业务线程池中执行，避免阻塞worker线程。
        pipeline.addLast(httpRequestHandler);
    }

}
